练习
1.(*1)将下面的for循环重写为采用while循环的等价形式:
for(i = 0; i < max_length; i++)
if(input_line[i] == '?') quest_count++;
重写这个片段,用一个指针作为被控制变量,其检测采用 *p == '?'的形式。
2.(*1)为下面各个表达式加上全部括号:
a = b + c * d << 2 & 8
a & 077 != 3
a == b || a == c && c < 5
c = x != 0
0 <= i < 7
f(1, 2) + 3
a = -1 ++ b -- - 5
a = b == c++
a = b = c = 0
a[4][2] *= *b ? c : *d * 2
a - b, c = d
3.(*2)读入一系列由空白分隔的(名字,值)对,其中每个名字是由空白分隔开的一个单词,值是一个整数或者一个浮点值。计算并打印出对应于每个名字的所有值之和与平均值,以及所有名字的和与平均值。提示:6.1.8节。
4.(*1)写出一个表格,其中列出各种可能的0和1组合作为运算对象,进行按位逻辑运算所得到(6.2.4节)的值。
5.(*1.5)找出5种不同的其意义无定义的C++结构(C.2节)。(*1.5)找出5种不同的其意义由实现确定的C++结构(C.2节)。
6.(*1)找出10个不可移植的C++代码的例子。
7.(*2)写出5个表达式,对它们的求值顺序没有定义。执行它们,看看某一个或(最好)多个实现对它们怎么做。
8.(*1.5)如果你在你的系统上除0会发生什么事情?在上溢和下溢时又会怎么样?
9.(*1)给下面各表达式加上全部括号:
*p++
*--p
++a--
(int*)p->m
*p.m
*a[i]
10.(*2)写出下面函数:strlen(),它返回C风格字符串的长度;strcpy(),它将一个C风格字符串复制到另一个;strcmp(),它比较两个C风格的字符串。考虑参数类型和返回值类型应该是什么。而后将你的函数与在<cstring>
(<string.h>
)里以及在20.1.4节描述的标准库版本做一个比较。
11.(*1)看看你的编译器对下面这些错误有何反应:
void f(int a, int b)
{
if(a = 3) // ...
if(a & 077 == 0) // ...
a := b + 1;
}
设计一些更简单的错误,并看看编译器如何反应。
12.(*2)修改6.6[3]的程序,使之同时计算出中间值。
13.(*2)写一个函数cat(),它取两个C风格字符串为参数,返回一个字符串,该字符串是两个参数串的拼接。利用new为这个结果取得存储。
14.(*2)写一个函数rev(),它取一个C风格字符串p为参数,并反转其中的字符。也就是说,在rev(p)之后p的最后一个字符将变成第一个,如此等等。
15.(*1.5)下面例子做些什么?
// Duff设施,有帮助的注释被有意删去了
void send(int* to, int* from, int count)
{
int n = (count + 7) / 8;
switch(count % 8) {
case 0: do { *to++ = *from++;
case 7: *to++ = *from++;
case 6: *to++ = *from++;
case 5: *to++ = *from++;
case 4: *to++ = *from++;
case 3: *to++ = *from++;
case 2: *to++ = *from++;
case 1: *to++ = *from++;
} while (--n > 0);
}
}
为什么会有人想写这样的东西?
16.(*2)写一个函数atoi(const char*),它以一个包含数字的C风格字符串为参数,返回与之对应的int值。例如,atoi("123")应是123。修改atoi(),使之除了能处理简单的十进制之外,还能处理C++的八进制和十六进制记法形式。修改atoi()以处理C++的字符常量记法。
17.(*2)写一个函数itoa(int i, char b[]),它在b中建立起i的字符串表示并返回b。
18.(*2)键入计算器的例子并使之能够工作。不要“节约时间”去使用已有的正文文件。你将会从发现并改正各种“小而蠢的错误”中学到许多东西。
19.(*2)修改计算器程序,使之能够在报告错误时给出相应的行号。
20.(*3)设法使用户可以在计算器中定义函数。提示:将一个函数定义为运算的一个序列,就像用户键入它们那样。这种序列可以存储为字符串,或者存储为单词的表。当函数被调用时,就读取并执行这些运算。如果你希望用户定义函数能够使用参数,那么你就必须为此去发明一种记法形式。
21.(*1.5)改造桌面计算器,让它使用一种symbol结构,而不是使用静态变量number_value和string_value。
22.(*2.5)写一个程序,使它能剥掉C++程序里的所有注释。即,从cin读入,删除所有的// 和/* */注释,而后将其写到cout。不要费力去把输出的布局弄得比较好看(那可以成为另外一个更困难的练习题),也不要去顾虑错误的程序。请留意位于注释、字符串和字符常量中的//、/*和*/。
23.(*2)去找一些程序,取得一些有关在实际中使用的缩进编排、命名和注释的认识。
🔚